package com.kk.xhr.admin.biz.impl;

import com.kk.xhr.admin.biz.ITransferBizService;
import com.kk.xhr.admin.controller.request.TransferAddRequest;
import com.kk.xhr.admin.controller.request.TransferQueryRequest;
import com.kk.xhr.admin.controller.vo.TransferVO;
import com.kk.xhr.common.ErrorCodeEnum;
import com.kk.xhr.common.exception.BusinessException;
import com.kk.xhr.common.pojo.BinaryEnum;
import com.kk.xhr.model.dto.DepartmentDTO;
import com.kk.xhr.model.dto.NotificationDTO;
import com.kk.xhr.model.dto.PageDto;
import com.kk.xhr.model.dto.PositionDTO;
import com.kk.xhr.model.dto.TransferDTO;
import com.kk.xhr.model.dto.TransferQueryRequestDTO;
import com.kk.xhr.model.dto.UserDTO;
import com.kk.xhr.model.service.IDepartmentService;
import com.kk.xhr.model.service.INotificationService;
import com.kk.xhr.model.service.IPositionService;
import com.kk.xhr.model.service.ITransferService;
import com.kk.xhr.model.service.IUserService;
import com.kk.xhr.util.DateUtil;
import com.kk.xhr.web.vo.PageVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 调岗biz服务接口实现
 *
 * @author kkmystery
 * @version 1.0 2021/3/8
 * @since 1.0.0
 */
@Service
@RequiredArgsConstructor
public class TransferBizServiceImpl implements ITransferBizService {
    private final ITransferService transferService;
    private final IDepartmentService departmentService;
    private final IPositionService positionService;
    private final IUserService userService;
    private final INotificationService notificationService;

    @Override
    public PageVO<TransferVO> queryPage(TransferQueryRequest request) {
        PageDto<TransferDTO> dtos = transferService.queryPage(TransferQueryRequestDTO.builder()
            .userId(request.getUserId())
            .begin(DateUtil.validTime(request.getBegin()))
            .end(DateUtil.validTime(request.getEnd()))
            .limit(request.getLimit())
            .offset(request.getOffset())
            .build());
        return PageVO.fromDTO(dtos, this::generateVO);
    }

    @Override
    public void add(TransferAddRequest request) {
        transferService.add(TransferDTO.builder()
            .userId(request.getUserId())
            .afterDepartmentId(request.getAfterDepartmentId())
            .afterJobId(request.getAfterJobId())
            .reason(request.getReason())
            .remark(request.getRemark())
            .removeDate(DateUtil.validTime(request.getRemoveDate()))
            .status(BinaryEnum.FALSE)
            .build());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean modifyStatus(Long id, BinaryEnum status) {
        TransferDTO transfer = transferService.queryById(id)
            .orElseThrow(() -> new BusinessException(ErrorCodeEnum.TRANSFER_NOT_EXIST));
        if (transfer.getStatus() == status) {
            return false;
        }
        if (BinaryEnum.TRUE == status) {
            UserDTO user = userService.queryById(transfer.getUserId())
                .orElseThrow(() -> new BusinessException(ErrorCodeEnum.USER_NOT_EXIST));
            DepartmentDTO department = departmentService.queryById(user.getDepartmentId())
                .orElseThrow(() -> new BusinessException(ErrorCodeEnum.DEPARTMENT_NOT_EXIST));
            if (department.getUserId().equals(user.getId())) {
                throw new BusinessException(ErrorCodeEnum.DEPARTMENT_CHANGE_FAIL);
            }
            userService.modify(UserDTO.builder()
                .id(user.getId())
                .departmentId(transfer.getAfterDepartmentId())
                .positionId(transfer.getAfterJobId())
                .build());
        }
        notificationService.add(NotificationDTO.builder()
            .userId(transfer.getUserId())
            .message("调岗审核已通过，即时生效")
            .build());
        return transferService.modifyStatus(id, status);
    }

    /**
     * TransferVO生成器
     *
     * @param dto TransferDTO
     * @return TransferVO
     */
    private TransferVO generateVO(TransferDTO dto) {
        DepartmentDTO department = departmentService.queryById(dto.getAfterDepartmentId())
            .orElse(DepartmentDTO.builder().name("无").build());
        PositionDTO position = positionService.queryById(dto.getAfterJobId())
            .orElse(PositionDTO.builder().name("无").build());
        return TransferVO.builder()
            .id(dto.getId())
            .name(userService.queryName(dto.getUserId()))
            .afterDepartmentName(department.getName())
            .afterJobName(position.getName())
            .reason(dto.getReason())
            .remark(dto.getRemark())
            .removeDate(dto.getRemoveDate())
            .status(dto.getStatus())
            .build();
    }
}
